#pragma once
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "log.hpp"
#include "error.hpp"

// 将进程守护进程化：
// 1.setsid
// 2.调用setsid不能以进程组长的身份运行
// 3.屏蔽一些异常信号
// 4.文件描述符的处理
// 5.更改路径 - 可选

void Daemon()
{
    // 1.屏蔽异常信号
    signal(SIGPIPE, SIG_IGN); // 忽略SIGPIPE信号
    signal(SIGCHLD, SIG_IGN);

    // 2.不以进程组长的身份运行
    if (fork() > 0)
        exit(0); // 父进程退出，让子进程去进程守护化

    // 3.调用setsid
    pid_t p = setsid();
    if(p == -1)
    {
        logMessage(Fatal,"setsid failed... %d %s",errno,strerror(errno));
        exit(SETSID_ERR);
    }
    // 4. 更改路径 - 可选
    //  chdir("/");

    // 5.对文件描述符的处理
    //  /del/null 是每个linux系统必须有的一个文件设备，可以往里面写的任何数据都被丢弃，读取的任何数据都为空
    int fd = open("/dev/null", O_RDWR);
    // int dup2(int oldfd, int newfd);
    dup2(fd, 0);
    dup2(fd, 1);
    dup2(fd, 2);
    close(fd);
}